let express = require('express');
let router = express.Router();
let mongoose = require('mongoose');
const request = require('request');
let formidable = require('formidable');
let path = require('path');
let fs = require('fs');
let os = require('os'); //node的内置模块，不需要安装
const { json } = require('body-parser');
let ifaces = os.networkInterfaces(); //用networkInterfaces方法获取网关信息
let address = '';
//循环获取到的网关信息
for (let dev in ifaces) {
    ifaces[dev].forEach(function (details) {
        //找到ipv4地址
        if (details.family === 'IPv4') {
            //127.0.0.1貌似也是ipv4地址的一个，所以需要排除
            if (details.address !== '127.0.0.1') {
                //拿到局域网的ipv4地址
                address = details.address
            }
        }
    });
}
conn = mongoose.createConnection('mongodb://127.0.0.1:27017/Index', { useNewUrlParser: true, useUnifiedTopology: true }, function (err) {
    if (err) {
        throw err;
    }
    else {
        console.log('database in running... IP:' + address);
    }
})



// 定义所有期
let allIssuesSchema = new mongoose.Schema({
    id: Number,
    name: String,
    strat_time: String,
    end_time: String,

})
let allIssuesModel = conn.model('allIssues', allIssuesSchema, 'allIssues');
// 定义所有卷子
let allPapersSchema = new mongoose.Schema({
    belongToIssue: Number,
    name: String,
    id: Number,
})
let allPapersModel = conn.model('allPapers', allPapersSchema, 'allPapers');
// 定义所有题目
let allQuestionsSchema = new mongoose.Schema({
    belongToPaper: Number,
    type: Number,
    id: Number,
})
let allQuesetionsModel = conn.model('allQuestions', allQuestionsSchema, 'allQuestions');

// 定义所有选择题
let allSelectQuestionsSchema = new mongoose.Schema({
    id: Number,
    discript: String,
    optionA: String,
    optionB: String,
    optionC: String,
    optionD: String,
    answer: String,
})
let allSelectQuestionsModel = conn.model('allSelectQuestions', allSelectQuestionsSchema, 'allSelectQuestions');

// 定义所有判断题
let allJudgeQuestionsSchema = new mongoose.Schema({
    id: Number,
    discript: String,
    answer: Boolean,
})
let allJudgeQuestionsModel = conn.model('allJudgeQuestions', allJudgeQuestionsSchema, 'allJudgeQuestions');

// 定义所有填空题
let allCompleteQuestionsSchema = new mongoose.Schema({
    id: Number,
    discript: String,
    answer: String,
})
let allCompleteQuestionsModel = conn.model('allCompleteQuestions', allCompleteQuestionsSchema, 'allCompleteQuestions');
// 定义用户信息
let studentsSchema = new mongoose.Schema({
    user_id: String,
    wx_id: String,
    name: String,
    year_No: String,
    class_No: String,
    school: String,
    student_No: String,
    avatarUrl: String,
    total_grade: Number
})
let studentsModel = conn.model('students', studentsSchema, 'students');

let paperGradeSchema = new mongoose.Schema({

    wx_id: String,
    paper_id: Number,
    paperName: String,
    score: Number,
    data: String
})
let paperGradeModel = conn.model('paperGrade', paperGradeSchema, 'paperGrade');
//存储答题模式，每套卷子的分数
router.get("/saveGrade1", (req, res) => {
    paperGradeModel.find({
        wx_id: req.query.wx_id,
        paper_id: req.query.paper_id
    }, "score").sort({ "score": -1 }).exec((e, dd) => {
        paperGradeModel.create({
            wx_id: req.query.wx_id,
            paper_id: req.query.paper_id,
            paperName: req.query.paperName,
            score: req.query.score,
            data: req.query.data
        }, (e, d) => {
            if (e) {
                console.log(e)
                res.send("No")
            } else {
                //把该用户该套卷子所有成绩拿出来排序，取最大加到总分中    

                if (dd.length) {
                    //console.log(dd)
                    let score = (dd[0].score)
                    //console.log(req.query.score,score)
                    let add_score = Number(req.query.score) - score
                    if (add_score > 0) {
                        studentsModel.findOne(
                            { wx_id: String(req.query.wx_id) },
                            "total_grade").exec((e, d) => {
                                //console.log(d.total_grade)
                                studentsModel.findOneAndUpdate({ wx_id: String(req.query.wx_id) }, {
                                    total_grade: d.total_grade + add_score
                                }).exec((e, d) => {
                                    if (!e) {
                                        res.send("Ok")
                                    }
                                })
                            })
                    } else {
                        res.send("此试卷已做过，最高得分" + score)
                    }
                } else {//如果dd为空 说明该用户未做过此套卷子，
                    //console.log("here"+req.query.score)

                    studentsModel.findOne(
                        { wx_id: String(req.query.wx_id) },
                        "total_grade").exec((e, d) => {
                            //console.log(d.total_grade)
                            studentsModel.findOneAndUpdate({ wx_id: String(req.query.wx_id) }, {
                                total_grade: d.total_grade + Number(req.query.score)
                            }).exec((e, d) => {
                                if (!e) {
                                    res.send("Ok")
                                }
                            })
                        })
                }

            }
        })
    })
})
//存储一站到底模式，本次挑战的结果,每一条记录都是该用户挑战的结果
let fightSchema = new mongoose.Schema({
    wx_id: String,
    score: String,
    data: String
})
let fightModel = conn.model('fight', fightSchema, 'fight');

router.get("/saveGrade2", (req, res) => {
    fightModel.create({
        wx_id: req.query.wx_id,
        score: req.query.score,
        data: req.query.data
    }, (e, d) => {
        if (e) {
            console.log(e)
            res.send("No")
        } else {
            studentsModel.findOne({ wx_id: String(req.query.wx_id) }, "total_grade").exec((e, d) => {
                //console.log(d.total_grade)
                studentsModel.findOneAndUpdate({ wx_id: String(req.query.wx_id) }, {
                    total_grade: d.total_grade + Number(req.query.score)
                }).exec((e, d) => {
                    if (!e) {
                        res.send("Ok")
                    }
                })
            })
        }
    })
})
router.get("/isRegister", (req, res) => {
    //console.log(req.query.wx_id)
    studentsModel.find({ wx_id: req.query.wx_id }).exec((err, data) => {
        console.log(data)
        if (data.length) {
            res.send("Yes")
        } else {
            res.send("No")
        }
    })
})
router.get("/get_myInfo", (req, res) => {
    //console.log(req.body)
    studentsModel.findOne({ wx_id: String(req.query.wx_id) }).exec((err, data) => {
        if (data) {
            res.send(data)
        } else {
            res.send("No User")
        }

    })
})
router.get("/get_myGrade", (req, res) => {
    //console.log(req.body)
    studentsModel.findOne({ wx_id: String(req.query.wx_id) }, "total_grade").exec((err, data) => {
        if (data) {
            res.send(data)
        } else {
            res.send("No User")
        }

    })
})

router.get("/get_record", (req, res) => {
    //console.log(req.body)
    paperGradeModel.find({ wx_id: req.query.wx_id }, "paperName score data")
        .sort({ data: -1 })
        .exec((e, d) => {
            res.send(d)
        })
    // paperGradeModel.aggregate([
    //     { $lookup: { from: 'allPapers', as: 'b_doc', localField: 'paper_id', foreignField: 'id' } },
    //     { $match: { 'wx_id': { $exists: false } } },
    // ]).exec((err, data) => {
    //     if (err) {
    //         console.log(err)
    //         res.send([])
    //     }
    //     else {
    //         res.send(data)
    //     }

    // })
})

router.get("/get_rankingList", (req, res) => {
    //console.log(req.body)
    studentsModel.find({}, { name: 1, total_grade: 1, avatarUrl: 1 }).limit(20).sort({ "total_grade": -1, "user_id": 1 }).exec((err, data) => {
        if (err) {
            console.log(err)
            res.send([])
        }
        else {
            res.send(data)
        }

    })
})
var rank_temp = []
function get_myRank(find_myRank, rank_back, rank_Send) {
    return new Promise((resolve, reject) => {
        router.get("/get_myRank", (req, res) => {
            studentsModel.findOne({ wx_id: String(req.query.wx_id) }, { name: 1, total_grade: 1, avatarUrl: 1, user_id: 1 }).exec((err, data) => {
                if (data) {
                    find_myRank(data, rank_back)
                    // data.rankNo = rank_temp[0].rankNo
                    setTimeout(rank_Send, 300, res, data)

                }
                else {
                    res.send(undefined)
                }
            })
        })
    })
}
function find_myRank(user, rank_back) {
    studentsModel.aggregate([
        {
            $sort:
                { total_grade: -1, user_id: 1 }
        },
        {
            $group:
                { _id: null, all: { $push: "$user_id" } }
        },
        {
            $project:
                { index: { $indexOfArray: ["$all", user.user_id] } }
        },
    ]).exec((err, data) => {
        if (err) {
            console.log(err)
        }
        else {
            rank_back(data)
        }

    })
}
function rank_back(obj) {
    rank_temp = obj
}
function rank_Send(res, user) {
    var test = {}
    test._id = user._id
    test.name = user.name
    test.user_id = user.user_id
    test.total_grade = user.total_grade
    test.avatarUrl = user.avatarUrl
    test.rankNo = rank_temp[0].index
    res.send(test)
    setTimeout(function () {
        rank_temp = []
        test = {}
    }, 200)
}
get_myRank(find_myRank, rank_back, rank_Send)

router.post("/register", (req, res) => {
    //console.log(req.body.wx_id)
    let user = JSON.parse(req.body.user)
    studentsModel.find({ wx_id: String(user.wx_id) }).exec((err, data) => {
        //console.log(data)
        if (err) {
            console.log(err)
        }
        else if (data.length) {
            res.send("该用户已注册")
            return
        } else {
            studentsModel.find().sort({ user_id: -1 }).limit(1).exec((err, data) => {

                user_id = String(Number(data[0].user_id) + 1)
                //console.log(user_id)
                studentsModel.create({
                    name: user.name,
                    school: user.school,
                    student_No: user.student_No,

                    year_No: user.phone,
                    class_No: user.class_No,

                    wx_id: user.wx_id,
                    user_id: user_id,
                    avatarUrl: user.avatarUrl,
                    total_grade: 0
                }, (err, data) => {
                    if (!err) {
                        res.send("Ok")
                    } else {
                        console.log(err)
                        res.send("False")
                    }
                })
            })
        }
    })


})


router.post("/set_info", (req, res) => {
    //console.log(req.body.wx_id)
    let user = JSON.parse(req.body.user)
    studentsModel.findOneAndUpdate({
        wx_id: String(user.wx_id)
    }, {
        $set: {
            name: user.name,
            school: user.school,
            student_No: user.student_No,
            year_No: user.year_No,
            class_No: user.class_No,
            avatarUrl: user.avatarUrl,
        }
    }).exec((e, d) => {
        if (e) {
            console.log(e)
        } else {
            res.send("OK")
        }
    })



})




//获取全部期
router.get("/get_issues.php", function (req, res) {
    allIssuesModel.find().exec(function (err, data) {

        if (!err) {
            paperGradeModel.find({ wx_id: req.query.wx_id }, "paper_id").exec((e, d) => {
                //console.log(d)
                let finished_papers = new Set()
                for (i in d) {
                    finished_papers.add(Number(d[i].paper_id))
                }
                let finished_issues = []
                finished_papers = Array.from(finished_papers)
                //console.log(finished_papers.length)
                for (let i = 0; i <= finished_papers.length - 2; i++) {
                    //console.log(finished_papers[i])
                    //console.log(`${i}`)
                    //首先看窗口开头值是不是1、4、7、10。。。
                    if ((finished_papers[i] - 1) % 3 == 0) {
                        //再看是不是连续的3个数
                        let strat = finished_papers[i]
                        let mid = finished_papers[i + 1]
                        let end = finished_papers[i + 2]
                        //console.log(strat,mid,end)
                        if (mid == strat + 1 && end == mid + 1) {
                            finished_issues.push((strat - 1) / 3 + 1)
                        }
                    }

                }
                const obj = { finished_issues: finished_issues, data: data }
                //data = Object.assign({}, data, obj)
                //console.log(finished_issues)
                console.log(obj)
                res.send(obj)
            })

        } else {
            console.log(err)
        }
    });
})
function randomNums(n, min, max) {
    var arr = [];
    for (i = 0; i < n; i++) {
        var ran = Math.ceil(Math.random() * (max - min) + min);
        while (isExist(arr, ran)) {
            ran = Math.ceil(Math.random() * (max - min) + min);
        }
        arr[i] = ran;
    }
    return arr;
}

function isExist(arr, ran) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] == ran) {
            return true;
        }
    }
    return false;
}
function fetchData2(select_, mySend) {
    router.get("/one_fight", (req, res) => {
        allQuesetionsModel.count().exec((err, count) => {
            // Get a random entry
            let arr = randomNums(10, 0, count)
            allQuesetionsModel.find({ q_id: { $in: arr } }).exec((err, data) => {
                console.log(data)
                for (i in data) {
                    question = data[i]
                    switch (Number(question.type)) {
                        case 0:
                            allSelectQuestionsModel.findOne({ id: Number(question.id) }).exec(function (err, data) {
                                const obj = { question_type: 0, question_name: "select" }
                                data = Object.assign({}, data._doc, obj)
                                select_(data)
                            })
                            break;
                        case 1:
                            allSelectQuestionsModel.findOne({ id: Number(question.id) }).exec(function (err, data) {
                                const obj = { question_type: 1, question_name: "multiSelect" }
                                data = Object.assign({}, data._doc, obj)
                                //console.log(data)
                                select_(data)
                                //multiSelect.push(JSON.stringify(data))
                            })
                            break;
                        case 2:
                            allJudgeQuestionsModel.findOne({ id: Number(question.id) }).exec(function (err, data) {
                                const obj = { question_type: 2, question_name: "judge" }
                                data = Object.assign({}, data._doc, obj)
                                //console.log(data)
                                select_(data)
                            })
                            break;
                        case 3:
                            allCompleteQuestionsModel.findOne({ id: Number(question.id) }).exec(function (err, data) {
                                const obj = { question_type: 3, question_name: "complete" }
                                data = Object.assign({}, data._doc, obj)

                                select_(data)
                            })
                            break;
                        default:
                            break;
                    }//switch
                }//for
                setTimeout(mySend, 400, res)
            })
        })
    })
}
fetchData2(select2, mySend2)
//获取openId
router.get("/get_openId.php", function (req, res) {
    let appid = "wx3f1eb4e8227ce8a0"
    let secret = "768850c117ae4c169f11bcdb5bee2b3d"
    let url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + secret
        + "&js_code=" + req.query.code + "&grant_type=authorization_code"
    var request = require('request');
    request({ url: url, json: true }, function (error, data) {
        if (!error) {
            //console.log(data.body.openid)
            studentsModel.find({ wx_id: String(data.body.openid) }).exec((err, d) => {
                //console.log(d)      
                if (d != undefined && d.length) {
                    res.send(["1", data.body.openid])
                } else {
                    res.send(["0", data.body.openid])
                }
            })

        }
    })
})
//获取某期全部卷子
router.get("/get_papers.php", function (req, res) {
    allPapersModel.find({ belongToIssue: Number(req.query.issueId) }, 'id name').exec(function (err, data) {
        if (!err) {
            console.log(data)
            res.send(data)
        }
    });
})
//获取某卷子全部题

var arr = []
var arr2 = []
function fetchData(select_, mySend) {
    router.get("/get_questions.php", function (req, res) {
        //console.log(Number(req.query.paperId))

        allQuesetionsModel.find({ belongToPaper: Number(req.query.paperId) }, 'id type').exec(function (err, data) {
            console.log(data)
            if (data != undefined) {
                for (i in data) {
                    question = data[i]
                    console.log(question)
                    console.log(question.type)
                    //foo(select, question.type, question.id)
                    switch (Number(question.type)) {
                        case 0:
                            allSelectQuestionsModel.findOne({ id: Number(question.id) }).exec(function (err, data) {
                                //select_("xxx")
                                const obj = { question_type: 0, question_name: "select" }
                                data = Object.assign({}, data._doc, obj)
                                select_(data)
                                //console.log(arr)

                            })
                            break;
                        case 1:
                            allSelectQuestionsModel.findOne({ id: Number(question.id) }).exec(function (err, data) {
                                const obj = { question_type: 1, question_name: "multiSelect" }
                                data = Object.assign({}, data._doc, obj)
                                //console.log(data)
                                select_(data)
                                //multiSelect.push(JSON.stringify(data))
                            })
                            break;

                        case 2:
                            allJudgeQuestionsModel.findOne({ id: Number(question.id) }).exec(function (err, data) {
                                const obj = { question_type: 2, question_name: "judge" }
                                data = Object.assign({}, data._doc, obj)
                                //console.log(data)
                                select_(data)
                            })
                            break;
                        case 3:
                            allCompleteQuestionsModel.findOne({ id: Number(question.id) }).exec(function (err, data) {
                                const obj = { question_type: 3, question_name: "complete" }
                                data = Object.assign({}, data._doc, obj)
                                //console.log(data)
                                select_(data)
                            })
                            break;
                        default:
                            break;
                    }//switch
                }//for
                setTimeout(mySend, 300, res)
            }//if
            else {
                res.send([])
            }
        });
    })

}
function select2(data) {
    arr2.push(data)
    //console.log(arr)
}
function mySend2(res) {
    res.send(arr2)
    arr2 = []
}
function select_(data) {
    arr.push(data)
    //console.log(arr)
}
function mySend(res) {
    res.send(arr)
    arr = []
}
fetchData(select_, mySend)


module.exports = router;
